home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 076-100 / scopedisk89 / uut / lc.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  7KB  |  367 lines

  1. /*
  2.  * lc - a directory lister in the style of the Waterloo lc for BSD Unix
  3.  *
  4.  * Copyright 1989 Edwin Hoogerbeets
  5.  *
  6.  * This code is freely redistributable as long as no charge other than
  7.  * reasonable copying fees is levied for it.
  8.  *
  9.  *
  10.  * Usage: lc [-dfa] [directory ...]
  11.  *
  12.  *    -d only list directories
  13.  *    -f only list files
  14.  *    -a all files  (useful for listing the directory called "-d")
  15.  *
  16.  */
  17. #include <stdio.h>
  18. #include <exec/memory.h>
  19. #include <libraries/dos.h>
  20. #include <ctype.h>
  21. #include <errno.h>
  22.  
  23. #define NUMFILES 500
  24. #define WIDTH 15
  25. #define FILENAMESIZE 31
  26. #define FIBSIZE (long)sizeof(struct FileInfoBlock)
  27. #define TABSIZE (long)NUMFILES*FILENAMESIZE
  28. #define isdir(a) (filetype(a) == 1)
  29.  
  30. typedef char (*filearray)[NUMFILES][FILENAMESIZE];
  31.  
  32. /* don't need no steekeen work bench */
  33. _wb_parse() {}
  34.  
  35. /*
  36.  * case insensitive compare strings. From edlib v1.1. Used with permission
  37.  * from the author. 8-)
  38.  */
  39. int stricmp(str1,str2)
  40. register char *str1,*str2;
  41. {
  42.   register int index = 0;
  43.  
  44.   while ( str1[index] && str2[index] &&
  45.           tolower(str1[index]) == tolower(str2[index]) )
  46.     ++index;
  47.  
  48.   return( (tolower(str1[index]) < tolower(str2[index])) ? -1 :
  49.         ( (tolower(str1[index]) > tolower(str2[index])) ?  1 : 0) );
  50. }
  51.  
  52.  
  53. extern char             *AllocMem();
  54. extern struct FileLock  *Lock();
  55.  
  56. /* also from edlib */
  57. int filetype(path)
  58. char *path;
  59. {
  60.   register struct FileInfoBlock *fib;
  61.   register struct FileLock *lock;
  62.   register int result;
  63.  
  64.  
  65.   if ( !(fib = (struct FileInfoBlock *) AllocMem(FIBSIZE,MEMF_CLEAR)) ) {
  66.     errno = ENOMEM;
  67.     return(-1);
  68.   }
  69.  
  70.   if ( !(lock = Lock(path,ACCESS_READ)) ) {
  71.     errno = EACCES;
  72.     return(-1);
  73.   }
  74.  
  75.   Examine(lock,fib);
  76.  
  77.   result = ( fib->fib_DirEntryType > 0 ) ? 1 : 0;
  78.  
  79.   UnLock(lock);
  80.   FreeMem(fib,FIBSIZE);
  81.  
  82.   return(result);
  83. }
  84.  
  85. int windowsize()
  86. {
  87.   register char c;
  88.   register int n = 0, width;
  89.   char buffer[32];
  90.  
  91.   set_raw();
  92.  
  93.   printf("\2330 q"); /* get window bounds */
  94.  
  95.   n = 0;
  96.  
  97.   while( (buffer[n] = getchar()) != 'r' && n++ < 32);
  98.  
  99.   c = buffer[n-3];
  100.  
  101.   width = ( (c <= '9' && c > '0') ? (c - '0') * 10 : 0 )
  102.           + buffer[n-2] - '0';
  103.  
  104.   buffer[n-1] = '\0';
  105.  
  106.   set_con();
  107.  
  108.   return(width);
  109. }
  110.  
  111. usage()
  112. {
  113.   fprintf(stderr,"Usage: lc [-dfa] [directory ...]\n");
  114.   exit(1);
  115. }
  116.  
  117. int dflag = 0;   /* display the directories? */
  118. int fflag = 0;   /* display the files? */
  119.  
  120. main(argc,argv)
  121. int argc;
  122. char **argv;
  123. {
  124.   register int index = 1;
  125.  
  126.   if ( argc > 1 ) {
  127.  
  128.     /* option must be first argument */
  129.     if ( *argv[index] == '-' ) {
  130.  
  131.       switch ( argv[index][1] ) {
  132.  
  133.         case 'd':
  134.  
  135.           /* only do directories */
  136.           dflag = 1;
  137.  
  138.           /* advance the index to the next argument */
  139.           ++index;
  140.           break;
  141.  
  142.         case 'f':
  143.  
  144.           /* only do files */
  145.           fflag = 1;
  146.  
  147.           /* advance the index to the next argument */
  148.           ++index;
  149.           break;
  150.  
  151.         case 'a':
  152.           /* do both, and skip this argument */
  153.           dflag = fflag = 1;
  154.           ++index;
  155.           break;
  156.  
  157.         default:
  158.           usage();
  159.           break;
  160.       }
  161.  
  162.     } else {
  163.       /* do both */
  164.       dflag = fflag = 1;
  165.     }
  166.  
  167.     switch ( argc - index ) {
  168.  
  169.       case 0:
  170.         lc("");
  171.         break;
  172.  
  173.       case 1:
  174.         lc(argv[index]);
  175.         break;
  176.  
  177.       default:
  178.         for ( ; index < argc ; index++ ) {
  179.           printf("%s contains:\n",argv[index]);
  180.           lc(argv[index]);
  181.           if ( index < argc -1 )  {
  182.             printf("\n");
  183.           }
  184.         }
  185.         break;
  186.      }
  187.   } else {
  188.     /* do both */
  189.     dflag = fflag = 1;
  190.  
  191.     lc("");
  192.   }
  193.  
  194.   exit(0);
  195. }
  196.  
  197. char *nomem = "Fatal: Not enough memory\n";
  198.  
  199. lc(dir)
  200. char *dir;
  201. {
  202.   register filearray dtab, ftab;
  203.   register struct FileLock *lock;
  204.   register struct FileInfoBlock *fib;
  205.   register int findex = 0, dindex = 0;
  206.   int i, j, foo;
  207.  
  208.   if ( !isdir(dir) ) {
  209.     printf("%s: not a directory\n\n",dir);
  210.     return(1);
  211.   }
  212.  
  213.   if ( !(dtab = (filearray) AllocMem(TABSIZE,MEMF_CLEAR)) ) {
  214.     fprintf(stderr,nomem);
  215.     exit(2);
  216.   }
  217.  
  218.   if ( !(ftab = (filearray) AllocMem(TABSIZE,MEMF_CLEAR)) ) {
  219.     fprintf(stderr,nomem);
  220.     FreeMem(dtab,TABSIZE);
  221.     exit(2);
  222.   }
  223.  
  224.   if ( !(fib = (struct FileInfoBlock *) AllocMem(FIBSIZE,MEMF_CLEAR)) ) {
  225.     fprintf(stderr,nomem);
  226.     FreeMem(ftab,TABSIZE);
  227.     FreeMem(dtab,TABSIZE);
  228.     exit(2);
  229.   }
  230.  
  231.   if ( !(lock = Lock(dir,ACCESS_READ)) ) {
  232.     fprintf("Error: Could not get a lock on directory %s\n",dir);
  233.     FreeMem(ftab,TABSIZE);
  234.     FreeMem(dtab,TABSIZE);
  235.     return(1);
  236.   }
  237.  
  238.   Examine(lock,fib);
  239.  
  240. #ifdef DEBUG
  241.   printf("directory: %s\n",&fib->fib_FileName[0]);
  242. #endif
  243.  
  244.   while ( ExNext(lock,fib) ) {
  245.     strncpy(fib->fib_DirEntryType > 0 ? &(*dtab)[dindex++] :
  246.             &(*ftab)[findex++],&fib->fib_FileName[0],FILENAMESIZE);
  247. #ifdef DEBUG
  248.     printf("file: %s\n",&fib->fib_FileName[0]);
  249. #endif
  250.   }
  251.  
  252. #ifdef DEBUG
  253.   printf("%d Directories and %d Files\n", dindex, findex);
  254.  
  255.   for ( i = 0 ; i < findex ; i++ ) {
  256.     printf("unsorted file %d: %s\n",i,&(*ftab)[i]);
  257.   }
  258. #endif
  259.  
  260.   if ( dflag && dindex ) {
  261.  
  262.     printf("Directories:\n");
  263.     list(dtab,dindex,FILENAMESIZE,stricmp);
  264.  
  265.   }
  266.  
  267.   if ( fflag && findex ) {
  268.  
  269.     if ( dflag && dindex ) {
  270.       printf("\n");
  271.     }
  272.  
  273.     printf("Files:\n");
  274.     list(ftab,findex,FILENAMESIZE,stricmp);
  275.  
  276.   }
  277.  
  278.   FreeMem(fib,FIBSIZE);
  279.   FreeMem(ftab,TABSIZE);
  280.   FreeMem(dtab,TABSIZE);
  281.   UnLock(lock);
  282.  
  283.   return(0);
  284. }
  285.  
  286. #define pad(x) (((x)<15)?16:32)
  287.  
  288. list(table,n,size,func)
  289. filearray table;
  290. int n, size;
  291. int (*func)();
  292. {
  293.   register int i, len, col, padded, rightcolumn = windowsize();
  294.  
  295.   if ( n > 1 ) {
  296.     quicksort(table,n,size,func);
  297.   }
  298.  
  299.   for ( i = 0, col = 0 ; i < n ; i++ ) {
  300.  
  301.     len = strlen(&(*table)[i]);
  302.     padded = len + WIDTH - len % WIDTH;
  303.  
  304.     if ( col + padded > rightcolumn ) {
  305.       printf("\n");
  306.       col = 0;
  307.     }
  308.  
  309.     col += padded;
  310.     printf("%-*s",padded,&(*table)[i]);
  311.  
  312.   }
  313.  
  314.   if ( col < rightcolumn )  {
  315.     printf("\n");
  316.   }
  317.  
  318. }
  319.  
  320. quicksort(array, n, size, func)
  321. char *array;
  322. int n, size;
  323. int (*func)();
  324. {
  325.    int b;
  326.  
  327.    if (n > 0) {
  328.       b = partition(&array[0], n, size, func);
  329.       quicksort(&array[0], b, size, func);
  330.       quicksort(&array[(b+1)*size], n - b - 1, size, func);
  331.    }
  332. }
  333.  
  334. partition(array, n, size, func)
  335. char *array;
  336. int n, size;
  337. int (*func)();
  338. {
  339.   int i, b;
  340.   char *pivot, *scr;
  341.  
  342.   scr = AllocMem((long)size,MEMF_CLEAR);
  343.  
  344.   pivot = &array[0];
  345.  
  346.   for (b = 0, i = 1; i < n; ++i) {
  347.  
  348.     if ( func(&array[(i)*size],pivot) < 0) {
  349.       ++b;
  350.       strncpy(scr,&array[(i)*size],size);
  351.       strncpy(&array[(i)*size],&array[(b)*size],size);
  352.       strncpy(&array[(b)*size],scr,size);
  353.     }
  354.   }
  355.  
  356.   strncpy(scr,&array[0],size);
  357.   strncpy(&array[0],&array[(b)*size],size);
  358.   strncpy(&array[(b)*size],scr,size);
  359.  
  360.   FreeMem(scr,(long)size);
  361.  
  362.   return (b);
  363. }
  364.  
  365.  
  366.  
  367.